﻿using System;
using System.Xml;
using System.Collections.Generic;

namespace Jtype1
{
    /// <summary>
    /// Class to serialize and deserialize <see cref="Jtype1.Task"/> objects
    /// and to read and write text files on disk storage
    /// </summary>
    public class DataStorage
    {
        /// <summary>
        /// Read XML data from a specific file and construct Task objects
        /// </summary>
        /// <param name="fileName">Name of the file to read, without extension name</param>
        /// <returns>
        /// A List of <see cref="Jtype1.Task"/> objects constructed from the file
        /// or a null pointer if fail to open the file
        /// </returns>
        public List<Task> readDataFromXMLFile(string fileName)
        {
            List<Task> taskList = new List<Task>();
            XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
            xmlReaderSettings.ValidationType = ValidationType.Schema;
            XmlReader reader = null;
            try
            {
                reader = XmlReader.Create(fileName + ".xml", xmlReaderSettings);
                if (reader.ReadState != ReadState.Error)
                {
                    Task currentTask;
                    taskList = new List<Task>();
                    while (reader.ReadToFollowing("task"))
                    {
                        currentTask = new Task();
                        currentTask.Index = Convert.ToInt32(reader.GetAttribute("index"));
                        currentTask.Priority = Convert.ToInt32(reader.GetAttribute("priority"));
                        currentTask.Status = Convert.ToInt32(reader.GetAttribute("status"));
                        reader.ReadToFollowing("name");
                        currentTask.Name = reader.ReadElementContentAsString();
                        reader.ReadToFollowing("location");
                        currentTask.Location = reader.ReadElementContentAsString();
                        reader.ReadToFollowing("deadline");
                        String temp = reader.ReadElementContentAsString();
                        currentTask.Deadline = DateTime.Parse(temp);
                        reader.ReadToFollowing("description");
                        currentTask.Description = reader.ReadElementContentAsString();
                        taskList.Add(currentTask);
                    }
                }
                return taskList;
            }
            catch (System.IO.FileNotFoundException)
            {
                Console.WriteLine(Error.FileError.FILE_NOT_FOUND);
                return null;
            }
            catch (System.Xml.XmlException)
            {
                Console.WriteLine(Error.FileError.XML_ERROR);
                return null;
            }
            finally
            {
                if (reader != null)
                    reader.Close();
            }
        }
        
        /// <summary>
        /// Write Task objects to a specific XML file
        /// </summary>
        /// <param name="fileName">Name of the file to write, without extension name</param>
        /// <param name="taskList">A List of Task objects to be saved in the file</param>
        /// <returns>Success of writing data to the XML file</returns>
        public Boolean writeDataToFile(string fileName, List<Task> taskList)
        {
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.Indent = true;
            xmlWriterSettings.IndentChars = ("\t");
            XmlWriter writer = XmlWriter.Create(fileName + ".xml", xmlWriterSettings);
            if (writer.WriteState != WriteState.Error)
            {
                writer.WriteStartElement("tasklist");
                foreach (Task currentTask in taskList)
                {
                    writer.WriteStartElement("task");
                    writer.WriteAttributeString("index", currentTask.Index.ToString());
                    writer.WriteAttributeString("priority", currentTask.Priority.ToString());
                    writer.WriteAttributeString("status", currentTask.Status.ToString());
                    writer.WriteStartElement("name");
                    writer.WriteString(currentTask.Name);
                    writer.WriteEndElement();
                    writer.WriteStartElement("location");
                    writer.WriteString(currentTask.Location);
                    writer.WriteEndElement();
                    writer.WriteStartElement("deadline");
                    writer.WriteString(currentTask.Deadline.ToString());
                    writer.WriteEndElement();
                    writer.WriteStartElement("description");
                    writer.WriteString(currentTask.Description);
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.Flush();
                writer.Close();
                return true;
            }
            else
            {
                return false;
            }
        }

    }
}
